/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.toolkit.shape;

import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.List;

import who.tmap.common.TMapException;

/**
 * An interface for polygons
 * @author stl
 *
 */
public interface PolygonShape extends MapShape, BaseMapShape {
	
	Object deepClone() throws CloneNotSupportedException;
	
    /**
     * add a point at the "end" of the polygon
     * @param pt
     */
	void addPoint( Point2D pt );
	void moveTo( Point2D pt );
	void lineTo( Point2D pt );
	
	/**
	 * Close the polygon
	 *
	 */
	void close();
	
	/**
	 * used by DAO layer and merge method
	 * @return
	 */
	GeneralPath getGeneralPath();
	void setGeneralPath( GeneralPath generalPath );
	
	/**
	 * Merge with another polygon
	 * @param polygonShape the other polygon to merge to
	 */
	void merge( PolygonShape polygonShape ) throws TMapException;
	
	/**
	 * Split the polygon into two polygons based on the line (firstPt, secondPt)
	 * @param firstPt
	 * @param secondPt
	 * @return the two polygons
	 */
	PolygonShape[] split( Point2D firstPt, Point2D secondPt ) throws TMapException;
	
	/**
	 * Add a common boundary
	 * @param polygonShape another polygon
	 * @param firstPt first point of the common boundary
	 * @param secondPt second point of the common boundary
	 * @param pathPt a point to define the path to choose
	 */
	void addCommonBoundary( PolygonShape polygonShape, 
	        				Point2D firstPt, Point2D secondPt, Point2D pathPt )
					throws TMapException;
	
	/**
	 * Returns the polygon's point coordinates of the specified handle
	 * @param handle the handle index
	 * @return the polygon's point coordinates
	 */
	Point2D getExactPointAtHandle( int handle );	
	
	/**
	 * 
	 * @param p
	 * @return true if p is an edge of the polygon
	 */
	boolean containsEdge( Point2D p );
	
	/**
	 * Remove a point from a polygon
	 * @param p the point coordinates to delete
	 */
	void removePointAt( Point2D p );	
	
	/**
	 * Move a polygon's point from origPt to newPt 
	 * @param origPt
	 * @param newPt
	 */
	void movePoint( Point2D origPt, Point2D newPt );

	/**
	 * Insert a new point on a polygon's segment
	 * @param p mouse click or exact point (exactly on the segment)
	 * @param exactPt is p an exact point or mouse click coordinates
	 * @return matching point if any otherwise null
	 */
	Point2D insertPoint( Point2D p, boolean exactPt );
	
	/**
	 * Set polygon's name. Can be assign with dbf shape file information
	 * @param name the polygon name
	 */
	void setName( String name );
	
	/**
	 * Returns polygon's name
	 * @return the polygon name
	 */
	String getName();
	
	void setLabelShape( LabelShape labelShape );
	LabelShape getLabelShape();
	
	/**
	 * Returns the center coordinates of the polygon
	 * @return
	 */
	Point2D getCenter();
	
	boolean addDisputedBorder( Point2D p, int strokeStyle );
	//void drawDisputedBorders( Graphics2D g2 );
	
	 List<PolygonShapeDisputedBorder> getDisputedBorders();
	 void setDisputedBorders( List<PolygonShapeDisputedBorder> disputedBorders );
	 
	 void setSegmentsVisible( boolean segmentsVisible );
	 boolean isSegmentsVisible();
	 
	 // For convenience purpose
	 void setLabelText( String labelText );
	 String getLabelText();
	 
	 /**
	  * Stores the Proportional Symbol bounding box
	  * when applicable
	  * @param psSymbolBounds
	  */
	 void setPsSymbolBounds( Rectangle2D psSymbolBounds );
	 Rectangle2D getPsSymbolBounds();

}

